
package com.ib.service;

import java.math.BigDecimal;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.ib.dto.ProcessingFee;
import com.ib.dto.TransactionAttribute;
import com.ib.enumertion.TransactionType;

/**
 * Processing of transaction.
 */
public class TransactionProcessingService implements ITransactionProcessingService {

	private static final Logger LOGGER = Logger.getLogger(TransactionProcessingService.class.getName());

	/**
	 * @see com.ib.service.ITransactionProcessingService.processTransaction(TransactionAttribute)
	 */
	@Override
	public ProcessingFee processTransaction(TransactionAttribute iTransaction) throws Exception {

		if (null == iTransaction) {
			// Throw business exception.
			throw new Exception("invalid case");
		}
		LOGGER.log(Level.FINE, "Processing Transaction: " + iTransaction);
		ProcessingFee processingFee = new ProcessingFee();
		processingFee.setClientId(iTransaction.getClientId());
		processingFee.setTransactionType(iTransaction.getTransactionType());
		processingFee.setTransactionDate(iTransaction.getDate());
		processingFee.setPriority(iTransaction.isPriorityFlag());
		processingFee.setProcessingFee(calculateFee(iTransaction));
		return processingFee;
	}

	/**
	 * Method to calculate processing fees. TODO: Can be moved to other class for fee processing.
	 * 
	 * @param iTransaction
	 * @return
	 * @throws Exception
	 */
	private BigDecimal calculateFee(TransactionAttribute iTransaction) throws Exception {

		// If high priority, fee is $500.
		if (iTransaction.isPriorityFlag()) {
			return new BigDecimal(500);
		} else {
			// in case of normal priority, if transaction type is "SELL" or
			// "Withdraw", fee is $100.
			if (iTransaction.getTransactionType() == TransactionType.SELL || iTransaction.getTransactionType() == TransactionType.WITHDRAW) {
				return new BigDecimal(100);
			} else if (iTransaction.getTransactionType() == TransactionType.BUY || iTransaction.getTransactionType() == TransactionType.DEPOSIT) {
				return new BigDecimal(50);
			} else {
				// Throw business exception for undefined rule.
				throw new Exception("Undefined rule");
			}
		}
	}
}